package com.samuel.blog.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;


@Component("redisUtil")
public class RedisUtil {
	private StringRedisTemplate redisTemplate;

	@Autowired
	public void setRedisTemplate(StringRedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	// =============================common============================
	public <T> void put(String key, T obj) {
		redisTemplate.opsForValue().set(key, JsonUtils.toJson(obj));
	}

	public <T> void put(String key, T obj, int timeout) {
		put(key, obj, timeout, TimeUnit.MINUTES);
	}

	public <T> void put(String key, T obj, int timeout, TimeUnit unit) {
		redisTemplate.opsForValue().set(key, JsonUtils.toJson(obj), timeout, unit);
	}

	public <T> void putList(String key, List<T> obj) {
		// 先删除
		delete(key);
		// 后添加
		ListOperations<String, String> opsForList = redisTemplate.opsForList();
		for (T t : obj) {
			opsForList.leftPush(key, JsonUtils.toJson(t));
		}
	}
	
	public <T> T get(String key, Class<T> cls) {
		return JsonUtils.fromJson(get(key), cls);
	}

	public <E, T extends Collection<E>> T get(String key, Class<E> cls, Class<T> collectionClass) {
		return JsonUtils.fromJson(get(key), cls, collectionClass);
	}
	
	public <E> List<E> getList(String key, Class<E> cls) {
		List<String> list = getList(key);
		List<E> lists = new ArrayList<E>();
		for (String obj : list) {
			if (!"[]".equals(obj)) {
				E fromJson = JsonUtils.fromJson(obj, cls);
				lists.add(fromJson);
			}
		}
		return lists;
	}


	/**
	 * 根据key查询是否存在
	 * @param key
	 * @return
	 */
	public boolean exists(String key) {
		return redisTemplate.hasKey(key);
	}

	/**
	 * 根据key删除
	 * @param key
	 */
	public void delete(String key) {
		redisTemplate.delete(key);
	}

	/**
	 * 通过key 设置过期
	 * @param key
	 * @param timeout		过期时间
	 * @param timeUnit		时间转换格式
	 * @return
	 */
	public boolean expire(String key, long timeout, TimeUnit timeUnit) {
		return redisTemplate.expire(key, timeout, timeUnit);
	}

	/**
	 * 通过key 设置过期 默认时间格式分
	 * @param key
	 * @param timeout
	 * @return
	 */
	public boolean expire(String key, long timeout) {
		return expire(key, timeout, TimeUnit.MINUTES);
	}

	/**
	 * 设置一个string格式的key 以及 string格式的值
	 * @param key
	 * @param value
	 */
	public void put(String key, String value) {
		redisTemplate.opsForValue().set(key, value);
	}

	/**
	 * 存储string格式的key以及string格式的值<br/>
	 *	并设置过期时间 默认时间格式-分
	 * @param key
	 * @param value
	 * @param timeout
	 */
	public void put(String key, String value, int timeout) {
		put(key, value, timeout, TimeUnit.MINUTES);
	}

	/**
	 * 存储string格式的key以及string格式的值<br/>
	 * 	根据格式转换
	 * @param key
	 * @param value
	 * @param timeout
	 * @param unit
	 */
	public void put(String key, String value, int timeout, TimeUnit unit) {
		redisTemplate.opsForValue().set(key, value, timeout, unit);
	}

	/**
	 * 根据key取值
	 * @param key
	 * @return
	 */
	public String get(String key) {
		return redisTemplate.opsForValue().get(key);
	}

	private List<String> getList(String key) {
		ListOperations<String, String> opsForList = redisTemplate.opsForList();
		return opsForList.range(key, 0, -1);
	}
}
